package com.example.game;

import androidx.appcompat.app.AppCompatActivity;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

class NumItem {
    int xNum = 0;
    int oNum = 0;

    public int GetXNum() {
        return this.xNum;
    }

    public int GetONum() {
        return this.oNum;
    }

    public void SetXNum(int num) {
        this.xNum += num;
    }

    public void SetONum(int num) {
        this.oNum += num;
    }
}

public class Game extends AppCompatActivity {
    private CountDownTimer countDownTimer;
    private boolean isForeground = true;
    private TextView timeView;
    public static Game instance;
    private GridView game_GridButton;
    private List<NumItem> rowNum = new ArrayList<>();
    private List<NumItem> columnNum = new ArrayList<>();
    private List<Icon> iconList = new ArrayList<>();
    private OriginState originState = new OriginState();
    private long remainingTimeInMillis = 60000; // 初始倒计时时间60秒

    private ServiceConnection serviceConnection = new ServiceConnection() {
        //回调函数，在与服务连接成功时被调用。
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.d("Clock", "onServiceConnected");
        }

        //回调函数，在绑定的服务断开连接时被调用
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.d("Clock", "onServiceDisconnected");
        }
    };

    //Activity的onCreate()生命周期方法的实现
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //布局文件activity_game.xml设置为Activity的用户界面
        setContentView(R.layout.activity_game);

        // 调用初始化 Spinner 的方法
        initTimeSelectionSpinner();

        // 设置选择计时时间的 Spinner 监听器
        setupTimeSelectionSpinner();
        //检查instance是否为null，如果是则将其赋值为当前Activity实例，实现单例模式
        if (instance == null) {
            instance = this;
        }
        // onCreate() 方法内部
        //找到id为R.id.Game_Pause_Button的按钮并设置点击监听器，点击时如果存在则进行取消倒计时
        Button pauseButton = findViewById(R.id.Game_Pause_Button);
        pauseButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (countDownTimer != null) {
                    countDownTimer.cancel(); // 取消倒计时
                }
            }
        });
        // onCreate() 方法内部
        Button continueButton = findViewById(R.id.Game_Continue_Button);
        continueButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startCountdown(remainingTimeInMillis); //开始倒计时剩余时间
            }
        });

        // 初始化继续游戏按钮
        continueButton = findViewById(R.id.Game_Continue_Button);
        continueButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startCountdown(remainingTimeInMillis); // 使用剩余时间重新开始计时
            }
        });

        // 初始化退出游戏按钮
        Button quitButton = findViewById(R.id.Game_Quit_Button);
        quitButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });


        // 初始化暂停游戏按钮
        pauseButton = findViewById(R.id.Game_Pause_Button);
        pauseButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (countDownTimer != null) {
                    countDownTimer.cancel();
                }
            }
        });

        //创建一个intent对象并使用bindService和startService方法绑定和启动名为Clock的服务
        Intent intent = new Intent(Game.this, Clock.class);
        bindService(intent, serviceConnection, BIND_AUTO_CREATE);
        startService(intent);

        InitData();

        //创建IconAdapter对象并将其设置为id为R.id.Game_GridButton的GridView的适配器
        IconAdapter iconAdapter = new IconAdapter(this, R.layout.item_grid_icon, iconList);
        game_GridButton = findViewById(R.id.Game_GridButton);
        // 设置适配器
        game_GridButton.setAdapter(iconAdapter);


        //GridView设置点击事件监听器，处理图标点击；逻辑(更改图标的图像和状态、更新用户界面、检查判断游戏是否输赢）
        game_GridButton.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

              //  Log.d("myapp","before Icon");

                //根据点击的项的索引从iconlist中获取对应的conc对象
                Icon icon = iconList.get(i);

              //  Log.d("myapp","before if");

                //判断Icon是否可以点击
                if(icon.GetCanClick()){

                //    Log.d("myapp","after if");

                    ImageView imageView = view.findViewById(R.id.item_img);
                    switch ((String)imageView.getTag()){
                        case "itemImage_null":
                            imageView.setImageResource(R.drawable.itemimage_x);
                            icon.SetIconId(1);
                            imageView.setTag("itemImage_x");
                            UpdateUI(i, 0);
                            break;
                        case "itemImage_x":
                            imageView.setImageResource(R.drawable.itemimage_o);
                            imageView.setTag("itemImage_o");
                            icon.SetIconId(2);
                            UpdateUI(i, 1);
                            break;
                        case "itemImage_o":
                            imageView.setImageResource(R.drawable.itemimage_null);
                            imageView.setTag("itemImage_null");
                            icon.SetIconId(0);
                            UpdateUI(i, 2);
                            break;
                    }
                }
//                else {
//                    Log.d("myapp","else");
//                }

                //TODO:将数据传进 IsWin() 函数
                boolean isWin = IsWin(i);

                if(isWin){
                    unbindService(serviceConnection);//解绑服务serviceConnection
                    stopService(new Intent(Game.this, Clock.class));//停止Clock服务
                    Intent intent = new Intent(Game.this, End.class);//创建一个跳转到End界面的intent
                    startActivity(intent);//启动该End类
                    Game.this.finish();
                }
                else Log.d("Game", "请继续解开谜题！");
            }

        });
//        // 启动初始倒计时
//        startNewCountdown();
    }
    public void InitData(){
        TypedArray images = getResources().obtainTypedArray(R.array.images);//从图片资源中获取一个包含图片的二维数组
        int[][] intArray = originState.GetState();//从originState对象中获取一个二维数组

        for(int i = 0; i < 8; i ++){//创建8行8列的rowItem和columnItem列表
            NumItem rowItem = new NumItem();
            NumItem columnItem = new NumItem();

            rowNum.add(rowItem);
            columnNum.add(columnItem);
        }

        for(int i = 0; i < 8; i++){
            for(int j = 0; j < 8; j++)
            {
                //创建Icon对象，根据数组元素的值设置Icon对象的图片ID
                Icon icon = new Icon();

                //TODO:Set ImageId
                icon.SetIconId(intArray[i][j]);
                icon.SetImageId(images.getResourceId(intArray[i][j], 0));

                if(intArray[i][j] != 0){
                    icon.SetIsRight(true);
                    icon.SetCanClick(false);

                    switch (intArray[i][j]){
                        case 1:
                            rowNum.get(i).SetXNum(1);
                            columnNum.get(j).SetXNum(1);
                            break;
                        case 2:
                            rowNum.get(i).SetONum(1);
                            columnNum.get(j).SetONum(1);
                            break;
                    }
                }
                else{
                    icon.SetCanClick(true);
                }
                iconList.add(icon);
            }
        }

        UpdateAllItem();
        Log.d("GridView", "数组长度为" + String.valueOf(iconList.size()));
    }

    //遍历答案数组和当前位置的图标数组，逐个比较判断是否相同。若不同则返回false、否则返回true
    public boolean IsWin(int position){
//        //TODO:判断是否胜利

        int point = 0;
        int[][] answer = originState.GetAnswer();

        for(int i = 0; i < 8; i ++){
            for(int j = 0; j < 8; j ++){
                if(iconList.get(point).GetIconId() != answer[i][j])
                    return false;
                point += 1;
            }
        }
        return true;
    }

//    public void SetChildRight(int position){
//        Icon frontIcon, behindIcon = null;
//        Icon icon = iconList.get(position);
//
//        if(position % 8 != 0 && position % 8 != 7){
//            frontIcon = iconList.get(position - 1);
//            behindIcon = iconList.get(position + 1);
//
//            int iconId = icon.GetIconId();
//            int frontId = frontIcon.GetIconId();
//            int behindId = behindIcon.GetIconId();
//
//            if(frontId != 0 && behindId != 0 && iconId != 0){
//                if(iconId == frontId && iconId != behindId || iconId != frontId && iconId == behindId){
//                    icon.SetIsRight(true);
//                }
//            }
//            else{
//                icon.SetIsRight(false);
//            }
//        }
//        else if(icon.GetIconId() != 0){
//            icon.SetIsRight(true);
//        }
//        else icon.SetIsRight(false);
//
//        //判断竖直方向
//        if(position > 7 && position < 56){
//            frontIcon = iconList.get(position - 8);
//            behindIcon = iconList.get(position + 8);
//
//            int iconId = icon.GetIconId();
//            int frontId = frontIcon.GetIconId();
//            int behindId = behindIcon.GetIconId();
//
//            if(frontId != 0 && behindId != 0 && iconId != 0){
//                if(iconId == frontId && iconId != behindId || iconId != frontId && iconId == behindId){
//                    icon.SetIsRight(true);
//                }
//            }
//            else{
//                icon.SetIsRight(false);
//            }
//        }
//        else if(icon.GetIconId() != 0){
//            icon.SetIsRight(true);
//        }
//        else icon.SetIsRight(false);
//    }
    //根据传入的参数更新UI界面。首先根据position计算出当前元素所在行和列。然后根据system的值进行不同的操作：
//    当system为0时，将行和列的数量加1；当system为1时，将该行和列的X数量减1，O数量加1。。。
//    最后调用UpdateonceItem(）方法更新行和列的UI界面
    private void UpdateUI(int position, int system){

        int row = position / 8;
        int column = position % 8;

        //更新行列数据
        switch (system){
            case 0:
                //从Null变成X，需要将X数量+1
                rowNum.get(row).SetXNum(1);
                columnNum.get(column).SetXNum(1);
                break;
            case 1:
                //从X变成O，需要将X数量-1，O数量+1
                rowNum.get(row).SetXNum(-1);
                columnNum.get(column).SetXNum(-1);
                rowNum.get(row).SetONum(1);
                columnNum.get(column).SetONum(1);
                break;
            case 2:
                //从O变成Null,需要将O数量-1
                rowNum.get(row).SetONum(-1);
                columnNum.get(column).SetONum(-1);
                break;
        }

        UpdateOneItem(row);
        UpdateOneItem(column);
    }

    //调用UpdateOneItem方法更新所有项目。循环迭代8次，每次将循环变量i作为参数传递给UpdateoneItem方法。
    private void UpdateAllItem() {
        for (int i = 0; i < 8; i++) {
            UpdateOneItem(i);
        }
    }

    //根据传入的索引i,更新对应位置的两个TextView的文本内容。
    private void UpdateOneItem(int i){
        //根据i的值，找到对应的roeItem和columnItem，然后再根据i的值设置对应的TextView文本内容（xNum/oNum)
        NumItem rowItem = rowNum.get(i);
        NumItem columnItem = columnNum.get(i);
        switch (i){
            case 0:
                SetText(findViewById(R.id.Left_TextView1), String.valueOf(rowItem.xNum) + "/" + String.valueOf(rowItem.oNum));
                SetText(findViewById(R.id.Up_TextView1), String.valueOf(columnItem.xNum) + "/" + String.valueOf(columnItem.oNum));
                break;
            case 1:
                SetText(findViewById(R.id.Left_TextView2), String.valueOf(rowItem.xNum) + "/" + String.valueOf(rowItem.oNum));
                SetText(findViewById(R.id.Up_TextView2), String.valueOf(columnItem.xNum) + "/" + String.valueOf(columnItem.oNum));
                break;
            case 2:
                SetText(findViewById(R.id.Left_TextView3), String.valueOf(rowItem.xNum) + "/" + String.valueOf(rowItem.oNum));
                SetText(findViewById(R.id.Up_TextView3), String.valueOf(columnItem.xNum) + "/" + String.valueOf(columnItem.oNum));
                break;
            case 3:
                SetText(findViewById(R.id.Left_TextView4), String.valueOf(rowItem.xNum) + "/" + String.valueOf(rowItem.oNum));
                SetText(findViewById(R.id.Up_TextView4), String.valueOf(columnItem.xNum) + "/" + String.valueOf(columnItem.oNum));
                break;
            case 4:
                SetText(findViewById(R.id.Left_TextView5), String.valueOf(rowItem.xNum) + "/" + String.valueOf(rowItem.oNum));
                SetText(findViewById(R.id.Up_TextView5), String.valueOf(columnItem.xNum) + "/" + String.valueOf(columnItem.oNum));
                break;
            case 5:
                SetText(findViewById(R.id.Left_TextView6), String.valueOf(rowItem.xNum) + "/" + String.valueOf(rowItem.oNum));
                SetText(findViewById(R.id.Up_TextView6), String.valueOf(columnItem.xNum) + "/" + String.valueOf(columnItem.oNum));
                break;
            case 6:
                SetText(findViewById(R.id.Left_TextView7), String.valueOf(rowItem.xNum) + "/" + String.valueOf(rowItem.oNum));
                SetText(findViewById(R.id.Up_TextView7), String.valueOf(columnItem.xNum) + "/" + String.valueOf(columnItem.oNum));
                break;
            case 7:
                SetText(findViewById(R.id.Left_TextView8), String.valueOf(rowItem.xNum) + "/" + String.valueOf(rowItem.oNum));
                SetText(findViewById(R.id.Up_TextView8), String.valueOf(columnItem.xNum) + "/" + String.valueOf(columnItem.oNum));
                break;
        }
    }

    //在SetText方法中添加空指针检查,检查传入的TestView对象是否为空，如果为空则不执行任何操作。避免了空指针异常的发生。
    private void SetText(TextView textView, String text) {
        if (textView != null) {
            textView.setText(text);
        }
    }

    public void SetTimeView(Intent intent){
        TextView textView = findViewById(R.id.Game_Time);
        textView.setText(String.valueOf(intent.getIntExtra("time", 0)));
    }

    private void initTimeSelectionSpinner() {
        Spinner timeSelectionSpinner = findViewById(R.id.spinner_time_selection);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
                R.array.time_selection_options, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        //过setAdapter方法将Adapter绑定到Spinner上，使得Spinner可以显示数组中的选项。
        timeSelectionSpinner.setAdapter(adapter);
    }

    private void setupTimeSelectionSpinner() {
        Spinner timeSelectionSpinner = findViewById(R.id.spinner_time_selection);
        timeSelectionSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
                switch (position) {
                    case 0:
                        remainingTimeInMillis = 120000; // 2分钟
                        break;
                    case 1:
                        remainingTimeInMillis = 300000; // 5分钟
                        break;
                    case 2:
                        remainingTimeInMillis = 600000; // 10分钟
                        break;
                    case 3:
                        remainingTimeInMillis = 1200000; // 20分钟
                        break;
                    case 4:
                        remainingTimeInMillis = 3600000; // 60分钟
                        break;
                }
                // 更新页面顶部的 TextView 显示倒计时
                updateTopTimeView(remainingTimeInMillis);
                // 如果倒计时已经开始，则重置并重新启动倒计时
                if (countDownTimer != null) {
                    countDownTimer.cancel();
                    startCountdown(remainingTimeInMillis);
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parentView) {
                // 未选择时不做任何操作
            }
        });
    }

    private void updateTopTimeView(long millisUntilFinished) {
        // Update UI with remaining time
        TextView timeView = findViewById(R.id.Game_Time);
        timeView.setText(String.format(Locale.getDefault(), "%d:%02d", millisUntilFinished / 60000, (millisUntilFinished % 60000) / 1000));
    }

    private void ResetGameToInitialState() {
        for (Icon icon : iconList) {
            icon.SetIconId(0);
            icon.SetIsRight(false);
            icon.SetCanClick(true);
        }

        IconAdapter iconAdapter = new IconAdapter(Game.this, R.layout.item_grid_icon, iconList);
        game_GridButton.setAdapter(iconAdapter);
        iconAdapter.notifyDataSetChanged();

        if (countDownTimer != null) {
            countDownTimer.cancel();
        }
        startNewCountdown();

        Log.d("Game", "游戏状态已重置至初始状态");
    }



    private BroadcastReceiver timeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            int timeInSeconds = intent.getIntExtra("time", 0);
            // 将秒转换为小时、分钟和秒
            int hours = timeInSeconds / 3600;
            int minutes = (timeInSeconds % 3600) / 60;
            int seconds = timeInSeconds % 60;

            // 格式化时间，确保它们都是两位数
            String formattedTime = String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds);

            TextView timeView = findViewById(R.id.Game_Time);
            timeView.setText(formattedTime);
        }
    };

    @Override
    protected void onPause() {
        super.onPause();
        // Cancel the countdown timer
        if (countDownTimer != null) {
            countDownTimer.cancel();
        }
    }

    //生命周期方法。检查应用程序是否返回前台，如果返回前台，则重新启动倒计时器，将remainingTimeInMillis作为倒计时的时间长度
    @Override
    protected void onResume() {
        super.onResume();
        // 如果应用程序返回前台，则重新启动倒计时器
        if (countDownTimer != null) {
            startCountdown(remainingTimeInMillis);
        }
    }


    private void startCountdown(long millisInFuture) {
        //如果过已有定时器存在，则取消之前的定时器
        if (countDownTimer != null) {
            countDownTimer.cancel();
        }

        //创建新的定时器
        countDownTimer = new CountDownTimer(millisInFuture, 1000) {
            public void onTick(long millisUntilFinished) {
                remainingTimeInMillis = millisUntilFinished;//将剩余时间保存至remainingTimeInMillis变量
                // 更新 UI 并显示剩余时间
                TextView timeView = findViewById(R.id.Game_Time);
                timeView.setText(String.format(Locale.getDefault(), "%d:%02d", millisUntilFinished / 60000, (millisUntilFinished % 60000) / 1000));
            }

            public void onFinish() {
                //当计时结束之后重新设置游戏状态
                ResetGameToInitialState();
            }
        }.start();
    }


    private void startNewCountdown() {
        startCountdown(remainingTimeInMillis); // 开始倒计时剩余时间
    }

}
